<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>设备监控面板</title>
    <!-- Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- Font Awesome -->
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    
    <!-- 配置Tailwind主题 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#3B82F6',
                        secondary: '#10B981',
                        warning: '#F59E0B',
                        danger: '#EF4444',
                        dark: '#1E293B',
                        light: '#F8FAFC'
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    
    <!-- 自定义工具类 -->
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            
            /* 设备卡片样式 */
            .device-card {
                @apply bg-white rounded-xl shadow-md p-5 mb-4 transition-all duration-300 hover:shadow-lg overflow-hidden;
            }
            
            /* 设备图标样式 */
            .device-icon {
                @apply text-3xl mb-2;
            }
            
            /* 状态指示器 */
            .status-indicator {
                @apply inline-block w-3 h-3 rounded-full mr-2;
            }
            
            /* 状态样式 */
            .status-on {
                @apply status-indicator bg-green-500 animate-pulse;
            }
            
            .status-off {
                @apply status-indicator bg-gray-400;
            }
            
            /* 传感器值样式 */
            .sensor-value {
                @apply text-lg font-semibold;
            }
            
            /* 刷新按钮样式 */
            .refresh-btn {
                @apply bg-primary hover:bg-primary/90 text-white font-medium py-2 px-4 rounded-lg transition-all duration-300 flex items-center;
            }
            
            /* 控制按钮样式 */
            .control-btn {
                @apply px-3 py-1 rounded text-sm font-medium transition-all duration-200 whitespace-nowrap;
            }
            
            .control-on {
                @apply control-btn bg-green-100 text-green-800 hover:bg-green-200;
            }
            
            .control-off {
                @apply control-btn bg-gray-100 text-gray-800 hover:bg-gray-200;
            }
            
            /* 火灾状态样式 */
            .fire-status {
                @apply px-3 py-1 rounded font-medium transition-all duration-300;
            }
            
            .fire-status-none {
                @apply fire-status bg-green-100 text-green-800;
            }
            
            .fire-status-exist {
                @apply fire-status bg-red-100 text-red-800 animate-pulse;
            }
            
            /* 自定义渐变背景 */
            .gradient-bg {
                @apply bg-gradient-to-br from-white to-gray-50;
            }
            
            /* 卡片悬停效果 */
            .card-hover {
                @apply hover:shadow-xl hover:-translate-y-1 transition-all duration-300;
            }
            
            /* 网络状态指示 */
            .network-status {
                @apply fixed bottom-4 right-4 z-50 rounded-full w-4 h-4 transition-all duration-500;
            }
            
            .network-online {
                @apply network-status bg-green-500 animate-pulse;
            }
            
            .network-offline {
                @apply network-status bg-red-500;
            }
            
            /* 摄像头容器样式 */
            .camera-container {
                @apply bg-white rounded-xl shadow-md p-5 mb-4 transition-all duration-300 overflow-hidden;
            }
            
            .camera-title {
                @apply text-xl font-semibold text-gray-800 mb-4 flex items-center;
            }
            
            .camera-feed {
                @apply w-full h-auto rounded-lg shadow-inner border border-gray-200 bg-gray-100;
            }
        }
    </style>
    
    <script>
        // 存储当前设备状态（使用数字值 1/0 表示开关状态）
        const deviceStates = {};
        
        // 网络状态
        let isNetworkOnline = true;
        
        // 请求重试配置
        const MAX_RETRIES = 3;
        let currentRetries = 0;
        
        // 设备图标映射（更新为工业Modbus TCP常用设备）
        const deviceIcons = {
            105: 'fa-tint',       // 空气质量
            302: 'fa-thermometer', // 温度
            303: 'fa-tint',       // 湿度
            301: 'fa-bolt',       // 设备电压
            308: 'fa-fire',       // 火灾情况
            106: 'fa-random',     // 震动频率
            306: 'fa-snowflake-o',// 制冷机
            304: 'fa-sun-o',      // 热风机
            305: 'fa-tint',       // 除湿机
            307: 'fa-lightbulb-o',// 照明灯
            101: 'fa-industry',   // 电磁阀
            102: 'fa-cog',        // 电机启动器
            103: 'fa-sliders',    // 电动阀门
            104: 'fa-lock'        // 安全门锁
        };
        
        // 设备名称映射（更新为工业Modbus TCP常用设备名称，删除数字）
        const deviceNames = {
            105: '空气质量',
            302: '温度',
            303: '湿度',
            301: '设备电压',
            308: '火灾情况',
            106: '震动频率',
            306: '制冷器',
            304: '加热器',
            305: '风机',
            307: '照明灯',
            101: '电磁阀',
            102: '电机启动器',
            103: '电动阀门',
            104: '安全门锁'
        };

        // 刷新时间间隔（毫秒）
        const REFRESH_INTERVAL = 5000;
        let autoRefreshInterval;
        let lastRefreshTime = null;
        let lastSuccessfulRefresh = null;

        function init() {
            // 创建网络状态指示器
            createNetworkIndicator();
            
            // 页面加载时自动刷新数据
            refresh();
            // 开启自动刷新
            autoRefreshInterval = setInterval(refresh, REFRESH_INTERVAL);
            
            // 显示初始刷新时间
            updateRefreshTime();
            
            // 添加页面加载动画
            document.body.classList.remove('opacity-0');
            
            // 初始化摄像头
            initCamera();
        }

        function stopAutoRefresh() {
            // 页面卸载时停止自动刷新
            clearInterval(autoRefreshInterval);
        }

        // 创建网络状态指示器
        function createNetworkIndicator() {
            const indicator = document.createElement('div');
            indicator.id = 'network-indicator';
            indicator.className = 'network-online';
            indicator.title = '网络连接正常';
            document.body.appendChild(indicator);
        }

        // 更新网络状态
        function updateNetworkStatus(online) {
            const indicator = document.getElementById('network-indicator');
            if (!indicator) return;
            
            if (online) {
                if (!isNetworkOnline) {
                    // 从离线变为在线时显示提示
                    showToast("网络连接已恢复", "success");
                }
                indicator.className = 'network-online';
                indicator.title = '网络连接正常';
            } else {
                indicator.className = 'network-offline';
                indicator.title = '网络连接断开';
                // 仅在网络状态变化时显示提示
                if (isNetworkOnline) {
                    showToast("网络连接断开，数据可能不实时更新", "warning");
                }
            }
            
            isNetworkOnline = online;
        }

        function refresh(force = false) {
            // 如果不是强制刷新且网络离线，则不执行请求
            if (!force && !isNetworkOnline) {
                console.log("网络离线，跳过自动刷新");
                return;
            }
            
            // 发送获取数据请求
            const xhr = new XMLHttpRequest();
            const url = "/get_data"; // 获取数据的 URL 路径
            xhr.open("GET", url, true);
            xhr.setRequestHeader("Content-Type", "application/json");
            
            // 设置超时时间
            xhr.timeout = 8000; // 8秒超时
            
            // 显示加载状态
            const refreshBtn = document.getElementById('refresh-btn');
            if (refreshBtn) {
                refreshBtn.disabled = true;
            }

            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    // 恢复按钮状态
                    if (refreshBtn) {
                        refreshBtn.disabled = false;
                    }
                    
                    if (xhr.status === 200) {
                        // 请求成功，重置重试计数
                        currentRetries = 0;
                        
                        // 更新网络状态
                        updateNetworkStatus(true);
                        
                        const response = xhr.responseText;
                        try {
                            const info = JSON.parse(response);
                            updateUI(info); // 更新页面显示
                            lastRefreshTime = new Date();
                            lastSuccessfulRefresh = lastRefreshTime;
                            updateRefreshTime();
                        } catch (error) {
                            console.error("数据解析失败:", error);
                            showToast("数据解析失败", "error");
                        }
                    } else {
                        // 请求失败，增加重试计数
                        currentRetries++;
                        
                        // 更新网络状态
                        updateNetworkStatus(false);
                        
                        console.error("请求失败:", xhr.status);
                        
                        // 仅在重试次数超过最大限制时显示提示
                        if (currentRetries >= MAX_RETRIES) {
                            showToast("网络连接不稳定，请稍后重试", "warning");
                            // 重置重试计数
                            currentRetries = 0;
                        }
                        
                        // 如果是强制刷新，无论如何都显示提示
                        if (force) {
                            showToast("刷新失败，请检查网络连接", "error");
                        }
                    }
                }
            };
            
            // 超时处理
            xhr.ontimeout = function() {
                // 恢复按钮状态
                if (refreshBtn) {
                    refreshBtn.disabled = false;
                }
                
                // 更新网络状态
                updateNetworkStatus(false);
                
                console.error("请求超时");
                
                // 仅在重试次数超过最大限制时显示提示
                if (currentRetries >= MAX_RETRIES) {
                    showToast("网络连接超时，请稍后重试", "warning");
                    // 重置重试计数
                    currentRetries = 0;
                }
                
                // 如果是强制刷新，无论如何都显示提示
                if (force) {
                    showToast("刷新超时，请检查网络连接", "error");
                }
            };

            xhr.send(); // 发送请求
        }

        // 强制刷新（用户点击）
        function forceRefresh() {
            // 显示加载状态
            const refreshBtn = document.getElementById('refresh-btn');
            const originalText = refreshBtn.innerHTML;
            refreshBtn.innerHTML = '<i class="fa fa-circle-o-notch fa-spin mr-2"></i> 刷新中...';
            refreshBtn.disabled = true;
            
            // 重置重试计数并强制刷新
            currentRetries = 0;
            refresh(true);
            
            // 恢复按钮状态
            setTimeout(() => {
                refreshBtn.innerHTML = originalText;
                refreshBtn.disabled = false;
            }, 1000);
        }

        // 更新刷新时间显示
        function updateRefreshTime() {
            const timeElement = document.getElementById('last-update');
            if (timeElement) {
                if (lastSuccessfulRefresh) {
                    const hours = String(lastSuccessfulRefresh.getHours()).padStart(2, '0');
                    const minutes = String(lastSuccessfulRefresh.getMinutes()).padStart(2, '0');
                    const seconds = String(lastSuccessfulRefresh.getSeconds()).padStart(2, '0');
                    timeElement.textContent = `${hours}:${minutes}:${seconds}`;
                    
                    // 显示网络状态提示
                    if (!isNetworkOnline) {
                        timeElement.innerHTML += '<span class="ml-2 text-red-500"><i class="fa fa-exclamation-circle"></i> 离线数据</span>';
                    }
                } else {
                    timeElement.textContent = "--";
                }
            }
        }

        function updateUI(data) {
            // 更新页面元素显示
            if (data.data) {
                data.data.forEach(item => {
                    const key = item.key;
                    // 处理布尔值或数字值，统一转换为数字 1/0
                    const val = item.val === true || item.val === "true" || item.val === 1 || item.val === "1" ? 1 : 0;
                    
                    // 存储设备状态（数字类型）
                    deviceStates[key] = val;
                    
                    // 格式化显示值（保留两位小数）
                    let displayVal = item.val;
                    // 对特定 key 的值保留两位小数
                    if ([105, 302, 303, 301].includes(key)) {
                        // 确保是数字类型再格式化
                        const numVal = parseFloat(item.val);
                        if (!isNaN(numVal)) {
                            displayVal = numVal.toFixed(2);
                        }
                    }
                    
                    // 更新UI元素
                    updateDeviceElement(key, displayVal, val);
                    
                    // 更新时间戳
                    updateTimestamp(key);
                });
            }
        }

        function updateDeviceElement(key, value, state) {
            const deviceElement = document.getElementById(`device-${key}`);
            if (!deviceElement) return;
            
            // 特殊处理火灾情况显示
            if (key === 308) {
                const fireStatusElement = deviceElement.querySelector('.sensor-value');
                if (fireStatusElement) {
                    fireStatusElement.className = state === 1 ? 'sensor-value fire-status fire-status-exist' : 'sensor-value fire-status fire-status-none';
                    fireStatusElement.textContent = state === 1 ? '有' : '无';
                    
                    // 更新状态指示器
                    const statusElement = deviceElement.querySelector('.status-indicator');
                    if (statusElement) {
                        statusElement.className = state === 1 ? 'status-indicator status-on' : 'status-indicator status-off';
                    }
                }
                return;
            }
            
            // 更新值显示
            const valueElement = deviceElement.querySelector('.sensor-value');
            if (valueElement) {
                valueElement.textContent = value;
            }
            
            // 更新状态指示
            const statusElement = deviceElement.querySelector('.status-indicator');
            if (statusElement) {
                statusElement.className = state === 1 ? 'status-indicator status-on' : 'status-indicator status-off';
            }
            
            // 更新开关状态
            const onBtn = deviceElement.querySelector('.control-on');
            const offBtn = deviceElement.querySelector('.control-off');
            if (onBtn && offBtn) {
                if (state === 1) {
                    onBtn.classList.add('ring-2', 'ring-green-500', 'font-bold');
                    offBtn.classList.remove('ring-2', 'ring-red-500', 'font-bold');
                } else {
                    onBtn.classList.remove('ring-2', 'ring-green-500', 'font-bold');
                    offBtn.classList.add('ring-2', 'ring-red-500', 'font-bold');
                }
            }
            
            // 更新卡片背景色（根据状态）
            if ([306, 304, 305, 307, 101, 102, 103, 104].includes(key)) {
                if (state === 1) {
                    deviceElement.classList.add('bg-green-50');
                    deviceElement.classList.remove('bg-white');
                } else {
                    deviceElement.classList.remove('bg-green-50');
                    deviceElement.classList.add('bg-white');
                }
            }
            
            // 如果网络离线，添加离线状态指示
            if (!isNetworkOnline) {
                deviceElement.classList.add('opacity-70');
                // 添加离线标签
                if (!deviceElement.querySelector('.offline-tag')) {
                    const offlineTag = document.createElement('div');
                    offlineTag.className = 'absolute top-2 right-2 bg-red-500 text-white text-xs px-2 py-1 rounded';
                    offlineTag.textContent = '离线';
                    offlineTag.classList.add('offline-tag');
                    deviceElement.appendChild(offlineTag);
                }
            } else {
                deviceElement.classList.remove('opacity-70');
                // 移除离线标签
                const offlineTag = deviceElement.querySelector('.offline-tag');
                if (offlineTag) {
                    deviceElement.removeChild(offlineTag);
                }
            }
        }

        // 更新时间戳
        function updateTimestamp(key) {
            const now = new Date();
            const timeString = now.toLocaleTimeString();
            const timeElement = document.getElementById(`${key}-time`);
            if (timeElement) {
                timeElement.textContent = `更新于 ${timeString}`;
            }
        }

        function toggleDevice(key, state) {
            // 如果网络离线，不执行操作并提示
            if (!isNetworkOnline) {
                showToast("网络连接断开，无法操作设备", "warning");
                return;
            }
            
            // 立即更新UI状态（使用数字类型 1/0）
            const newVal = state === 'on' ? 1 : 0;
            
            // 更新设备UI状态
            updateDeviceElement(key, deviceStates[key], newVal);
            
            // 显示设备开关状态提示
            const deviceName = deviceNames[key];
            const action = newVal === 1 ? '开启' : '关闭';
            showToast(`${deviceName}已${action}`, 'success');
            
            // 发送设置请求
            sendSetting(key, newVal);
        }

        // 更新震动频率函数
        function updateVibrationFrequency() {
            // 如果网络离线，不执行操作并提示
            if (!isNetworkOnline) {
                showToast("网络连接断开，无法设置参数", "warning");
                return;
            }
            
            const key = 106;
            // 获取输入框的值
            const val = parseInt(document.getElementById('106-input').value, 10);
            
            // 验证输入是否有效
            if (isNaN(val)) {
                showToast("请输入有效的数字", "warning");
                return;
            }
            
            // 限制范围
            const minVal = 0;
            const maxVal = 100;
            const clampedVal = Math.min(Math.max(val, minVal), maxVal);
            
            // 更新输入框值
            document.getElementById('106-input').value = clampedVal;
            
            // 更新显示值
            document.getElementById('106').textContent = clampedVal;
            
            // 显示设置提示
            showToast(`震动频率已设置为${clampedVal}Hz`, 'success');
            
            // 发送设置请求
            sendSetting(key, clampedVal);
        }

        function sendSetting(key, val) {
            // 显示加载状态
            const loadingElement = document.getElementById(`device-${key}`);
            if (loadingElement) {
                loadingElement.classList.add('opacity-70');
            }
            
            // 发送设备设置请求
            const xhr = new XMLHttpRequest();
            const url = "/control"; // 设置设备的 URL 路径

            // 构造设置请求数据
            const requestData = {
                "type": 2, // 2 表示设置数据请求
                "data": {
                    "key": key,
                    "val": val // 确保发送数字类型
                }
            };

            xhr.open("POST", url, true);
            xhr.setRequestHeader("Content-Type", "application/json");
            
            // 设置超时时间
            xhr.timeout = 8000; // 8秒超时

            xhr.onreadystatechange = function () {
                // 隐藏加载状态
                if (loadingElement) {
                    loadingElement.classList.remove('opacity-70');
                }
                
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        const response = xhr.responseText;
                        try {
                            const result = JSON.parse(response);
                            if (result.status === "ok") {
                                console.log(`设备 ${key} 设置成功，当前值: ${val}`);
                                // 更新本地状态
                                deviceStates[key] = val;
                            } else {
                                console.error("设置失败:", result.message);
                                showToast("设置失败：" + result.message, "error");
                                // 失败时恢复之前的状态
                                refresh();
                            }
                        } catch (error) {
                            console.error("设置响应解析失败:", error);
                            showToast("设置响应解析失败", "error");
                            // 发生错误时恢复之前的状态
                            refresh();
                        }
                    } else {
                        console.error("请求失败:", xhr.status);
                        showToast("设置请求失败，请检查网络连接", "error");
                        // 失败时恢复之前的状态
                        refresh();
                    }
                }
            };
            
            // 超时处理
            xhr.ontimeout = function() {
                // 隐藏加载状态
                if (loadingElement) {
                    loadingElement.classList.remove('opacity-70');
                }
                
                console.error("设置请求超时");
                showToast("设置请求超时，请检查网络连接", "error");
                // 失败时恢复之前的状态
                refresh();
            };

            xhr.send(JSON.stringify(requestData)); // 发送设置请求
        }

        // 显示提示消息
        function showToast(message, type = "info") {
            // 检查是否已存在相同类型和内容的toast
            const existingToasts = document.querySelectorAll('.toast-message');
            for (const toast of existingToasts) {
                if (toast.textContent.includes(message) && toast.classList.contains(type)) {
                    // 重置toast的消失计时器
                    clearTimeout(toast.timeoutId);
                    toast.timeoutId = setTimeout(() => {
                        toast.classList.add('translate-x-full', 'opacity-0');
                        setTimeout(() => {
                            document.body.removeChild(toast);
                        }, 300);
                    }, 3000);
                    return;
                }
            }
            
            // 创建toast元素
            const toast = document.createElement('div');
            toast.className = 'toast-message fixed top-4 right-4 px-4 py-2 rounded-lg shadow-lg flex items-center z-50 transition-all duration-300 transform translate-x-full opacity-0';
            
            // 添加类型类
            toast.classList.add(type);
            
            // 设置样式和内容
            let bgColor, textColor, icon;
            switch(type) {
                case "success":
                    bgColor = "bg-green-500";
                    textColor = "text-white";
                    icon = "fa-check-circle";
                    break;
                case "error":
                    bgColor = "bg-red-500";
                    textColor = "text-white";
                    icon = "fa-times-circle";
                    break;
                case "warning":
                    bgColor = "bg-yellow-500";
                    textColor = "text-white";
                    icon = "fa-exclamation-triangle";
                    break;
                default:
                    bgColor = "bg-blue-500";
                    textColor = "text-white";
                    icon = "fa-info-circle";
            }
            
            toast.className += ` ${bgColor} ${textColor}`;
            toast.innerHTML = `<i class="fa ${icon} mr-2"></i> ${message}`;
            
            // 添加到页面
            document.body.appendChild(toast);
            
            // 显示动画
            setTimeout(() => {
                toast.classList.remove('translate-x-full', 'opacity-0');
            }, 10);
            
            // 设置自动关闭计时器
            toast.timeoutId = setTimeout(() => {
                toast.classList.add('translate-x-full', 'opacity-0');
                setTimeout(() => {
                    document.body.removeChild(toast);
                }, 300);
            }, 3000);
        }
        
        // 初始化摄像头
        function initCamera() {
            const cameraFeed = document.getElementById('camera-feed');
            if (!cameraFeed) return;
            
            // 添加加载状态
            cameraFeed.innerHTML = `
                <div class="flex items-center justify-center h-64">
                    <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
                </div>
            `;
            
            // 创建图像元素
            const img = document.createElement('img');
            img.src = "http://192.168.50.239:8080/?action=stream";
            img.alt = "摄像头实时画面";
            img.className = "camera-feed";
            img.onerror = handleCameraError;
            
            // 替换加载状态
            setTimeout(() => {
                cameraFeed.innerHTML = '';
                cameraFeed.appendChild(img);
            }, 1000);
        }
        
        // 处理摄像头错误
        function handleCameraError() {
            const cameraFeed = document.getElementById('camera-feed');
            if (!cameraFeed) return;
            
            // 显示错误消息
            cameraFeed.innerHTML = `
                <div class="flex flex-col items-center justify-center h-64 p-4">
                    <i class="fa fa-video-camera text-gray-400 text-5xl mb-4"></i>
                    <p class="text-red-500 text-center">无法连接到摄像头</p>
                    <p class="text-gray-500 text-sm mt-2">请检查摄像头是否在线以及URL是否正确</p>
                    <button onclick="initCamera()" class="mt-4 px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-refresh mr-1"></i> 重试
                    </button>
                </div>
            `;
        }
    </script>
</head>

<body onload="init()" onunload="stopAutoRefresh()" class="bg-gray-50 font-sans opacity-0 transition-opacity duration-500">
    <!-- 导航栏 -->
    <nav class="bg-white shadow-md sticky top-0 z-40">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
            <div class="flex justify-between h-16">
                <div class="flex items-center">
                    <a href="index.html" class="flex-shrink-0 flex items-center">
                        <i class="fa fa-dashboard text-primary text-2xl mr-2"></i>
                        <span class="text-lg font-medium text-gray-900">设备监控面板</span>
                    </a>
                </div>
                <div class="flex items-center">
                    <button id="refresh-btn" class="refresh-btn flex items-center" onclick="forceRefresh()">
                        <i class="fa fa-refresh mr-2"></i>
                        <span>强制刷新</span>
                    </button>
                </div>
            </div>
        </div>
    </nav>

    <!-- 主内容区 -->
    <main class="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
        <!-- 状态概览 -->
        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-8">
            <!-- 空气质量 -->
            <div id="device-105" class="device-card card-hover bg-gradient-to-br from-blue-50 to-blue-100">
                <div class="flex items-center justify-between">
                    <div>
                        <i class="fa fa-tint text-blue-500 device-icon"></i>
                        <h3 class="font-semibold text-gray-800">空气质量</h3>
                    </div>
                    <span class="sensor-value text-blue-600">--</span>
                </div>
                <div class="mt-2 text-sm text-gray-600">
                    <i class="fa fa-clock-o mr-1"></i>
                    <span id="105-time">更新于 --</span>
                </div>
            </div>

            <!-- 温度 -->
            <div id="device-302" class="device-card card-hover bg-gradient-to-br from-red-50 to-red-100">
                <div class="flex items-center justify-between">
                    <div>
                        <i class="fa fa-thermometer text-red-500 device-icon"></i>
                        <h3 class="font-semibold text-gray-800">温度</h3>
                    </div>
                    <span class="sensor-value text-red-600">--</span>
                </div>
                <div class="mt-2 text-sm text-gray-600">
                    <i class="fa fa-clock-o mr-1"></i>
                    <span id="302-time">更新于 --</span>
                </div>
            </div>

            <!-- 湿度 -->
            <div id="device-303" class="device-card card-hover bg-gradient-to-br from-blue-50 to-blue-100">
                <div class="flex items-center justify-between">
                    <div>
                        <i class="fa fa-tint text-blue-500 device-icon"></i>
                        <h3 class="font-semibold text-gray-800">湿度</h3>
                    </div>
                    <span class="sensor-value text-blue-600">--</span>
                </div>
                <div class="mt-2 text-sm text-gray-600">
                    <i class="fa fa-clock-o mr-1"></i>
                    <span id="303-time">更新于 --</span>
                </div>
            </div>

            <!-- 设备电压 -->
            <div id="device-301" class="device-card card-hover bg-gradient-to-br from-yellow-50 to-yellow-100">
                <div class="flex items-center justify-between">
                    <div>
                        <i class="fa fa-bolt text-yellow-500 device-icon"></i>
                        <h3 class="font-semibold text-gray-800">设备电压</h3>
                    </div>
                    <span class="sensor-value text-yellow-600">--</span>
                </div>
                <div class="mt-2 text-sm text-gray-600">
                    <i class="fa fa-clock-o mr-1"></i>
                    <span id="301-time">更新于 --</span>
                </div>
            </div>
        </div>

        <!-- 火灾情况 -->
        <div id="device-308" class="device-card card-hover bg-gradient-to-br from-red-50 to-red-100 mb-8">
            <div class="flex items-center justify-between">
                <div>
                    <i class="fa fa-fire text-red-500 device-icon"></i>
                    <h3 class="font-semibold text-gray-800">火灾情况</h3>
                </div>
                <div class="flex items-center">
                    <span class="status-indicator status-off"></span>
                    <span class="sensor-value fire-status fire-status-none">无</span>
                </div>
            </div>
            <div class="mt-2 text-sm text-gray-600">
                <i class="fa fa-clock-o mr-1"></i>
                <span id="308-time">更新于 --</span>
            </div>
        </div>

        <!-- 震动频率 -->
        <div id="device-106" class="device-card card-hover bg-gradient-to-br from-purple-50 to-purple-100 mb-8">
            <div class="flex items-center justify-between">
                <div>
                    <i class="fa fa-random text-purple-500 device-icon"></i>
                    <h3 class="font-semibold text-gray-800">震动频率</h3>
                </div>
                <div class="flex items-center">
                    <span class="sensor-value text-purple-600" id="106">--</span>
                    <span class="ml-2 text-gray-600">Hz</span>
                </div>
            </div>
            <div class="mt-4 flex items-center">
                <input type="number" id="106-input" placeholder="输入震动频率" min="0" max="100" class="border border-gray-300 rounded-lg px-3 py-2 mr-2 focus:outline-none focus:ring-2 focus:ring-purple-500 w-full max-w-xs">
                <button type="button" onclick="updateVibrationFrequency()" class="bg-purple-500 hover:bg-purple-600 text-white font-medium py-2 px-4 rounded-lg transition-all duration-300">
                    更新
                </button>
            </div>
            <div class="mt-2 text-sm text-gray-600">
                <i class="fa fa-clock-o mr-1"></i>
                <span id="106-time">更新于 --</span>
            </div>
        </div>

        <!-- 摄像头画面 -->
        <div class="camera-container card-hover">
            <h2 class="camera-title">
                <i class="fa fa-video-camera text-primary mr-2"></i>
                摄像头监控
            </h2>
            <div id="camera-feed" class="camera-feed">
                <div class="flex items-center justify-center h-64">
                    <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
                </div>
            </div>
        </div>

        <!-- 设备控制区 -->
        <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
            <i class="fa fa-cogs text-primary mr-2"></i>
            设备控制
        </h2>
        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-4">
            <!-- 制冷器 -->
            <div id="device-306" class="device-card card-hover">
                <div class="flex items-center justify-between">
                    <div>
                        <i class="fa fa-snowflake-o text-blue-500 device-icon"></i>
                        <h3 class="font-semibold text-gray-800">制冷器</h3>
                    </div>
                    <div class="flex items-center">
                        <span class="status-indicator status-off"></span>
                        <div class="ml-2 flex">
                            <button id="306-on" class="control-on" onclick="toggleDevice(306, 'on')">开</button>
                            <button id="306-off" class="control-off ring-2 ring-red-500 font-bold" onclick="toggleDevice(306, 'off')">关</button>
                        </div>
                    </div>
                </div>
                <div class="mt-2 text-sm text-gray-600">
                    <i class="fa fa-clock-o mr-1"></i>
                    <span id="306-time">更新于 --</span>
                </div>
            </div>

            <!-- 加热器 -->
            <div id="device-304" class="device-card card-hover">
                <div class="flex items-center justify-between">
                    <div>
                        <i class="fa fa-sun-o text-yellow-500 device-icon"></i>
                        <h3 class="font-semibold text-gray-800">加热器</h3>
                    </div>
                    <div class="flex items-center">
                        <span class="status-indicator status-off"></span>
                        <div class="ml-2 flex">
                            <button id="304-on" class="control-on" onclick="toggleDevice(304, 'on')">开</button>
                            <button id="304-off" class="control-off ring-2 ring-red-500 font-bold" onclick="toggleDevice(304, 'off')">关</button>
                        </div>
                    </div>
                </div>
                <div class="mt-2 text-sm text-gray-600">
                    <i class="fa fa-clock-o mr-1"></i>
                    <span id="304-time">更新于 --</span>
                </div>
            </div>

            <!-- 风机 -->
            <div id="device-305" class="device-card card-hover">
                <div class="flex items-center justify-between">
                    <div>
                        <i class="fa fa-tint text-blue-500 device-icon"></i>
                        <h3 class="font-semibold text-gray-800">风机</h3>
                    </div>
                    <div class="flex items-center">
                        <span class="status-indicator status-off"></span>
                        <div class="ml-2 flex">
                            <button id="305-on" class="control-on" onclick="toggleDevice(305, 'on')">开</button>
                            <button id="305-off" class="control-off ring-2 ring-red-500 font-bold" onclick="toggleDevice(305, 'off')">关</button>
                        </div>
                    </div>
                </div>
                <div class="mt-2 text-sm text-gray-600">
                    <i class="fa fa-clock-o mr-1"></i>
                    <span id="305-time">更新于 --</span>
                </div>
            </div>

            <!-- 照明灯 -->
            <div id="device-307" class="device-card card-hover">
                <div class="flex items-center justify-between">
                    <div>
                        <i class="fa fa-lightbulb-o text-yellow-500 device-icon"></i>
                        <h3 class="font-semibold text-gray-800">照明灯</h3>
                    </div>
                    <div class="flex items-center">
                        <span class="status-indicator status-off"></span>
                        <div class="ml-2 flex">
                            <button id="307-on" class="control-on" onclick="toggleDevice(307, 'on')">开</button>
                            <button id="307-off" class="control-off ring-2 ring-red-500 font-bold" onclick="toggleDevice(307, 'off')">关</button>
                        </div>
                    </div>
                </div>
                <div class="mt-2 text-sm text-gray-600">
                    <i class="fa fa-clock-o mr-1"></i>
                    <span id="307-time">更新于 --</span>
                </div>
            </div>

            <!-- 电磁阀 -->
            <div id="device-101" class="device-card card-hover">
                <div class="flex items-center justify-between">
                    <div>
                        <i class="fa fa-industry text-primary device-icon"></i>
                        <h3 class="font-semibold text-gray-800">电磁阀</h3>
                    </div>
                    <div class="flex items-center">
                        <span class="status-indicator status-off"></span>
                        <div class="ml-2 flex">
                            <button id="101-on" class="control-on" onclick="toggleDevice(101, 'on')">开</button>
                            <button id="101-off" class="control-off ring-2 ring-red-500 font-bold" onclick="toggleDevice(101, 'off')">关</button>
                        </div>
                    </div>
                </div>
                <div class="mt-2 text-sm text-gray-600">
                    <i class="fa fa-clock-o mr-1"></i>
                    <span id="101-time">更新于 --</span>
                </div>
            </div>

            <!-- 电机启动器 -->
            <div id="device-102" class="device-card card-hover">
                <div class="flex items-center justify-between">
                    <div>
                        <i class="fa fa-cog text-warning device-icon"></i>
                        <h3 class="font-semibold text-gray-800">电机启动器</h3>
                    </div>
                    <div class="flex items-center">
                        <span class="status-indicator status-off"></span>
                        <div class="ml-2 flex">
                            <button id="102-on" class="control-on" onclick="toggleDevice(102, 'on')">开</button>
                            <button id="102-off" class="control-off ring-2 ring-red-500 font-bold" onclick="toggleDevice(102, 'off')">关</button>
                        </div>
                    </div>
                </div>
                <div class="mt-2 text-sm text-gray-600">
                    <i class="fa fa-clock-o mr-1"></i>
                    <span id="102-time">更新于 --</span>
                </div>
            </div>

            <!-- 电动阀门 -->
            <div id="device-103" class="device-card card-hover">
                <div class="flex items-center justify-between">
                    <div>
                        <i class="fa fa-sliders text-secondary device-icon"></i>
                        <h3 class="font-semibold text-gray-800">电动阀门</h3>
                    </div>
                    <div class="flex items-center">
                        <span class="status-indicator status-off"></span>
                        <div class="ml-2 flex">
                            <button id="103-on" class="control-on" onclick="toggleDevice(103, 'on')">开</button>
                            <button id="103-off" class="control-off ring-2 ring-red-500 font-bold" onclick="toggleDevice(103, 'off')">关</button>
                        </div>
                    </div>
                </div>
                <div class="mt-2 text-sm text-gray-600">
                    <i class="fa fa-clock-o mr-1"></i>
                    <span id="103-time">更新于 --</span>
                </div>
            </div>

            <!-- 安全门锁 -->
            <div id="device-104" class="device-card card-hover">
                <div class="flex items-center justify-between">
                    <div>
                        <i class="fa fa-lock text-info device-icon"></i>
                        <h3 class="font-semibold text-gray-800">安全门锁</h3>
                    </div>
                    <div class="flex items-center">
                        <span class="status-indicator status-off"></span>
                        <div class="ml-2 flex">
                            <button id="104-on" class="control-on" onclick="toggleDevice(104, 'on')">锁定</button>
                            <button id="104-off" class="control-off ring-2 ring-red-500 font-bold" onclick="toggleDevice(104, 'off')">解锁</button>
                        </div>
                    </div>
                </div>
                <div class="mt-2 text-sm text-gray-600">
                    <i class="fa fa-clock-o mr-1"></i>
                    <span id="104-time">更新于 --</span>
                </div>
            </div>
        </div>
    </main>

    <!-- 页脚 -->
    <footer class="bg-white border-t border-gray-200 mt-8">
        <div class="max-w-7xl mx-auto py-4 px-4 sm:px-6 lg:px-8">
            <p class="text-center text-sm text-gray-500">
                <i class="fa fa-copyright mr-1"></i> 2025 设备监控系统 | 最后更新时间: <span id="last-update">--</span>
            </p>
        </div>
    </footer>
</body>
</html>    